package com.example.config;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;

/**
 * 自定义过滤器第二种写法
 */
@Component
public class RequestTime2GatewayFilterFactory extends AbstractGatewayFilterFactory<RequestTime2GatewayFilterFactory.Config> {
    private static final Log log = LogFactory.getLog(GatewayFilter.class);
    private static final String REQUEST_TIME_BEGIN = "requestTimeBegin";
    private static final String KEY = "flag";

    public RequestTime2GatewayFilterFactory() {
        super(RequestTime2GatewayFilterFactory.Config.class);
    }

    public List<String> shortcutFieldOrder() {
        return Arrays.asList(KEY);
    }//指定配置的属性名

    public GatewayFilter apply(final RequestTime2GatewayFilterFactory.Config config) {
        return new GatewayFilter() {
            public Mono<Void> filter(final ServerWebExchange exchange, GatewayFilterChain chain) {
                return chain.filter(exchange).then(
                     Mono.<Void>fromRunnable(new Runnable() {
                         public void run() {
                             Long startTime = exchange.getAttribute(REQUEST_TIME_BEGIN);
                             if (startTime != null) {
                                 StringBuilder sb = new StringBuilder(exchange.getRequest().getURI().getRawPath())
                                         .append(": ")
                                         .append(System.currentTimeMillis() - startTime)
                                         .append("ms");
                                 if (config.isFlag()) {
                                     sb.append(" params:").append(exchange.getRequest().getQueryParams());
                                 }
                                 log.info(sb.toString());
                             }
                         }
                     })
                );
            }
        };
    }

    public static class Config {

        private boolean flag;

        public boolean isFlag() {
            return flag;
        }

        public void setFlag(boolean flag) {
            this.flag = flag;
        }

    }
}
